/**
 * 
 */
package com.nope.dodkr;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 * @author nope0102
 *
 */
public class DODXMLWorker {
	
	private static final String tagName = "skill";
	
	@SuppressWarnings("unchecked")
	public static List<DODItem> getDistinctStrings(String rootPath, String[] targetAttributes, String[] excludeTags, int limit) throws ParserConfigurationException, SAXException, IOException{
		
		Map<String, DODItem> result = new HashMap<String, DODItem>();
		DODItem dodItem = null;
		DODContext dodContext = null;
		
		File rootDir = new File(rootPath);
		//System.out.println(rootDir);
		Iterator<File> xmlIterator = FileUtils.iterateFiles(rootDir, new String[]{"xml"}, true);
		List<File> xmlFiles = IteratorUtils.toList(xmlIterator);
		
		DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
		Document document = null;
		DocumentTraversal documentTraversal = null;
		NodeIterator nodeIterator = null;
		NamedNodeMap attrMap = null;
		String value = null;
		
		int idx = 0;
		
		BREAK: 
		for(File xml : xmlFiles){
			
			//튜토리얼 파일 일단 제외
			if(xml.getName().contains("tutorial")){
				continue;
			}
			
			try{
				document = documentBuilder.parse(xml);
			} catch (SAXParseException e) {
				System.out.println(xml.getAbsolutePath());
				e.printStackTrace();
			}
			document.getDocumentElement().normalize();
			
			documentTraversal = (DocumentTraversal) document;
			nodeIterator = documentTraversal.createNodeIterator(document.getDocumentElement(), NodeFilter.SHOW_ELEMENT, new NodeFilter() {
				NamedNodeMap tempMap = null;
				@Override
				public short acceptNode(Node node) {
					tempMap = node.getAttributes();
					if(tempMap.getNamedItem("name") != null 
							|| tempMap.getNamedItem("text") != null 
							|| tempMap.getNamedItem("description") != null 
							|| tempMap.getNamedItem("subtype") != null){
						return 1;
					} else {
						return 0;
					}
				}
			}, true);
			for(Node node = nodeIterator.nextNode();node!= null;node = nodeIterator.nextNode()){
				//System.out.println(node.getNodeName());
				if(ArrayUtils.contains(excludeTags, node.getNodeName())){
					continue;
				}
				attrMap = node.getAttributes();
				int length = attrMap.getLength();
				for(int i = 0; i<length; i++){
					if(attrMap.item(i).getNodeType() == Element.ATTRIBUTE_NODE){
						if(ArrayUtils.contains(targetAttributes, attrMap.item(i).getNodeName())){
							
							dodContext = new DODContext();
							dodContext.setFileName(node.getBaseURI());
							dodContext.setTagName(node.getNodeName());
							dodContext.setContext(attrMap.item(i).toString());
							
							//System.out.println();
							value = attrMap.item(i).getNodeValue();
							if(StringUtils.isNotEmpty(value)
									&& !value.startsWith("#") 
									&& !value.startsWith(" ")
									//&& Character.isUpperCase(value.charAt(0))
							){
								if(result.containsKey(value)){
									dodItem = result.get(value);
									dodItem.setKeyText(value);
									dodItem.getContextList().add(dodContext);
								} else {
									dodItem = new DODItem();
									dodItem.setKeyText(value);
									dodItem.setContextList(new ArrayList<DODContext>());
									dodItem.getContextList().add(dodContext);
									idx++;
								}
								result.put(value, dodItem);
								//System.out.println(idx);
								if(idx >= limit){
									break BREAK;
								}
							}
						}
					}
				}
			}
		}
		
		List<DODItem> list = new ArrayList<DODItem>(result.values());
		Collections.sort(list, new Comparator<DODItem>() {
			
			public int compare(DODItem o1, DODItem o2) {
				
				
				
				if(this.hasContext(o1, tagName) && !this.hasContext(o2, tagName)){
					return -1;
				} else if(!this.hasContext(o1, tagName) && this.hasContext(o2, tagName)){
					return 1;
				} else {
					return 0;
				}
			}

			private boolean hasContext(DODItem dodItem, String tagName) {
				for(DODContext dodContext : dodItem.getContextList()){
					if( tagName.equals(dodContext.getTagName()) ){
						return true;
					}
				}
				return false;
			}
		});
		
		//번역된 건 뒤로
		Collections.sort(list, new Comparator<DODItem>(){
			
			@Override
			public int compare(DODItem o1, DODItem o2) {
				if(this.isTranslated(o1.getKeyText()) && !this.isTranslated(o2.getKeyText())){
					return 1;
				} else if(!this.isTranslated(o1.getKeyText()) && this.isTranslated(o2.getKeyText())){
					return -1;
				} else {
					return 0;
				}
			}
			
			private boolean isTranslated(String keyText) {
				for(int i = 0; i<keyText.length(); i++){
					if(Character.getType(keyText.charAt(i)) == 5){
						return true;
					}
				}
				return false;
			}
			
		});
		return list;
	}
	
	public static boolean isTranslated(String value){
		for(int i = 0; i<value.length(); i++){
			if(Character.getType(value.charAt(i)) == 5){
				return true;
			}
		}
		return false;
	}
	
	public static int countTranslated(List<DODItem> list){
		int cnt = 0;
		String keyText = null;
		for(DODItem dodItem : list){
			keyText = dodItem.getKeyText();
			if(DODXMLWorker.isTranslated(keyText)){
				cnt++;
			}
		}
		
		return cnt;
	}
	
	@SuppressWarnings("unchecked")
	public static void changeValueAndSaveFile(String rootPath, String from, String to) throws IOException{
		File rootDir = new File(rootPath);
		Iterator<File> xmlIterator = FileUtils.iterateFiles(rootDir, new String[]{"xml"}, true);
		List<File> xmlFiles = IteratorUtils.toList(xmlIterator);
		String text = null;
		for(File xml : xmlFiles){
			text = FileUtils.readFileToString(xml);
			//from = "\"" + from + "\"";
			//to = "\"" + to + "\"";
			if(text.contains(from)){
				System.out.println("##### WORKING FILE : " + xml.getAbsolutePath() );
				System.out.println("##### FROM : " + "\"" + from + "\"");
				System.out.println("##### TO : " + "\"" + to + "\"" );
				text = text.replace("\"" + from + "\"", "\"" + to + "\"");
				FileUtils.writeStringToFile(xml, text);
				System.out.println("##### CHANGED!!");
				System.out.println();
			}
		}
	}
	
}
